1   /*
2    * Copyright (C) 2007 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.base;
18  
19  import static com.google.common.base.Preconditions.checkNotNull;
20  
21  import com.google.common.annotations.GwtCompatible;
22  
23  import java.util.Arrays;
24  
25  import javax.annotation.CheckReturnValue;
26  import javax.annotation.Nullable;
27  
28  /**
29   * Helper functions that can operate on any {@code Object}.
30   *
31   * <p>See the Guava User Guide on <a
32   * href="http://code.google.com/p/guava-libraries/wiki/CommonObjectUtilitiesExplained">writing
33   * {@code Object} methods with {@code Objects}</a>.
34   *
35   * @author Laurence Gonsalves
36   * @since 2.0 (imported from Google Collections Library)
37   */
38  @GwtCompatible
39  public final class Objects {
40    private Objects() {}
41  
42    /**
43     * Determines whether two possibly-null objects are equal. Returns:
44     *
45     * <ul>
46     * <li>{@code true} if {@code a} and {@code b} are both null.
47     * <li>{@code true} if {@code a} and {@code b} are both non-null and they are
48     *     equal according to {@link Object#equals(Object)}.
49     * <li>{@code false} in all other situations.
50     * </ul>
51     *
52     * <p>This assumes that any non-null objects passed to this function conform
53     * to the {@code equals()} contract.
54     *
55     * <p><b>Note for Java 7 and later:</b> This method should be treated as
56     * deprecated; use {@link java.util.Objects#equals} instead.
57     */
58    @CheckReturnValue
59    public static boolean equal(@Nullable Object a, @Nullable Object b) {
60      return a == b || (a != null && a.equals(b));
61    }
62  
63    /**
64     * Generates a hash code for multiple values. The hash code is generated by
65     * calling {@link Arrays#hashCode(Object[])}. Note that array arguments to
66     * this method, with the exception of a single Object array, do not get any
67     * special handling; their hash codes are based on identity and not contents.
68     *
69     * <p>This is useful for implementing {@link Object#hashCode()}. For example,
70     * in an object that has three properties, {@code x}, {@code y}, and
71     * {@code z}, one could write:
72     * <pre>   {@code
73     *   public int hashCode() {
74     *     return Objects.hashCode(getX(), getY(), getZ());
75     *   }}</pre>
76     *
77     * <p><b>Warning:</b> When a single object is supplied, the returned hash code
78     * does not equal the hash code of that object.
79     *
80     * <p><b>Note for Java 7 and later:</b> This method should be treated as
81     * deprecated; use {@link java.util.Objects#hash} instead.
82     */
83    public static int hashCode(@Nullable Object... objects) {
84      return Arrays.hashCode(objects);
85    }
86  
87    /**
88     * Creates an instance of {@link ToStringHelper}.
89     *
90     * <p>This is helpful for implementing {@link Object#toString()}.
91     * Specification by example: <pre>   {@code
92     *   // Returns "ClassName{}"
93     *   Objects.toStringHelper(this)
94     *       .toString();
95     *
96     *   // Returns "ClassName{x=1}"
97     *   Objects.toStringHelper(this)
98     *       .add("x", 1)
99     *       .toString();
100    *
101    *   // Returns "MyObject{x=1}"
102    *   Objects.toStringHelper("MyObject")
103    *       .add("x", 1)
104    *       .toString();
105    *
106    *   // Returns "ClassName{x=1, y=foo}"
107    *   Objects.toStringHelper(this)
108    *       .add("x", 1)
109    *       .add("y", "foo")
110    *       .toString();
111    *
112    *   // Returns "ClassName{x=1}"
113    *   Objects.toStringHelper(this)
114    *       .omitNullValues()
115    *       .add("x", 1)
116    *       .add("y", null)
117    *       .toString();
118    *   }}</pre>
119    *
120    * <p>Note that in GWT, class names are often obfuscated.
121    *
122    * @param self the object to generate the string for (typically {@code this}),
123    *        used only for its class name
124    * @since 2.0
125    * @deprecated Use {@link MoreObjects#toStringHelper(Object)} instead. This
126    *     method is scheduled for removal in June 2016.
127    */
128   @Deprecated
129   public static ToStringHelper toStringHelper(Object self) {
130     return new ToStringHelper(MoreObjects.simpleName(self.getClass()));
131   }
132 
133   /**
134    * Creates an instance of {@link ToStringHelper} in the same manner as
135    * {@link Objects#toStringHelper(Object)}, but using the name of {@code clazz}
136    * instead of using an instance's {@link Object#getClass()}.
137    *
138    * <p>Note that in GWT, class names are often obfuscated.
139    *
140    * @param clazz the {@link Class} of the instance
141    * @since 7.0 (source-compatible since 2.0)
142    * @deprecated Use {@link MoreObjects#toStringHelper(Class)} instead. This
143    *     method is scheduled for removal in June 2016.
144    */
145   @Deprecated
146   public static ToStringHelper toStringHelper(Class<?> clazz) {
147     return new ToStringHelper(MoreObjects.simpleName(clazz));
148   }
149 
150   /**
151    * Creates an instance of {@link ToStringHelper} in the same manner as
152    * {@link Objects#toStringHelper(Object)}, but using {@code className} instead
153    * of using an instance's {@link Object#getClass()}.
154    *
155    * @param className the name of the instance type
156    * @since 7.0 (source-compatible since 2.0)
157    * @deprecated Use {@link MoreObjects#toStringHelper(String)} instead. This
158    *     method is scheduled for removal in June 2016.
159    */
160   @Deprecated
161   public static ToStringHelper toStringHelper(String className) {
162     return new ToStringHelper(className);
163   }
164 
165   /**
166    * Returns the first of two given parameters that is not {@code null}, if
167    * either is, or otherwise throws a {@link NullPointerException}.
168    *
169    * <p><b>Note:</b> if {@code first} is represented as an {@link Optional},
170    * this can be accomplished with
171    * {@linkplain Optional#or(Object) first.or(second)}.
172    * That approach also allows for lazy evaluation of the fallback instance,
173    * using {@linkplain Optional#or(Supplier) first.or(Supplier)}.
174    *
175    * @return {@code first} if {@code first} is not {@code null}, or
176    *     {@code second} if {@code first} is {@code null} and {@code second} is
177    *     not {@code null}
178    * @throws NullPointerException if both {@code first} and {@code second} were
179    *     {@code null}
180    * @since 3.0
181    * @deprecated Use {@link MoreObjects#firstNonNull} instead. This method is
182    *      scheduled for removal in June 2016.
183    */
184   @Deprecated
185   public static <T> T firstNonNull(@Nullable T first, @Nullable T second) {
186     return MoreObjects.firstNonNull(first, second);
187   }
188 
189   /**
190    * Support class for {@link Objects#toStringHelper}.
191    *
192    * @author Jason Lee
193    * @since 2.0
194    * @deprecated Use {@link MoreObjects.ToStringHelper} instead. This class is
195    *      scheduled for removal in June 2016.
196    */
197   @Deprecated
198   public static final class ToStringHelper {
199     private final String className;
200     private ValueHolder holderHead = new ValueHolder();
201     private ValueHolder holderTail = holderHead;
202     private boolean omitNullValues = false;
203 
204     /**
205      * Use {@link Objects#toStringHelper(Object)} to create an instance.
206      */
207     private ToStringHelper(String className) {
208       this.className = checkNotNull(className);
209     }
210 
211     /**
212      * Configures the {@link ToStringHelper} so {@link #toString()} will ignore
213      * properties with null value. The order of calling this method, relative
214      * to the {@code add()}/{@code addValue()} methods, is not significant.
215      *
216      * @since 12.0
217      */
218     public ToStringHelper omitNullValues() {
219       omitNullValues = true;
220       return this;
221     }
222 
223     /**
224      * Adds a name/value pair to the formatted output in {@code name=value}
225      * format. If {@code value} is {@code null}, the string {@code "null"}
226      * is used, unless {@link #omitNullValues()} is called, in which case this
227      * name/value pair will not be added.
228      */
229     public ToStringHelper add(String name, @Nullable Object value) {
230       return addHolder(name, value);
231     }
232 
233     /**
234      * Adds a name/value pair to the formatted output in {@code name=value}
235      * format.
236      *
237      * @since 11.0 (source-compatible since 2.0)
238      */
239     public ToStringHelper add(String name, boolean value) {
240       return addHolder(name, String.valueOf(value));
241     }
242 
243     /**
244      * Adds a name/value pair to the formatted output in {@code name=value}
245      * format.
246      *
247      * @since 11.0 (source-compatible since 2.0)
248      */
249     public ToStringHelper add(String name, char value) {
250       return addHolder(name, String.valueOf(value));
251     }
252 
253     /**
254      * Adds a name/value pair to the formatted output in {@code name=value}
255      * format.
256      *
257      * @since 11.0 (source-compatible since 2.0)
258      */
259     public ToStringHelper add(String name, double value) {
260       return addHolder(name, String.valueOf(value));
261     }
262 
263     /**
264      * Adds a name/value pair to the formatted output in {@code name=value}
265      * format.
266      *
267      * @since 11.0 (source-compatible since 2.0)
268      */
269     public ToStringHelper add(String name, float value) {
270       return addHolder(name, String.valueOf(value));
271     }
272 
273     /**
274      * Adds a name/value pair to the formatted output in {@code name=value}
275      * format.
276      *
277      * @since 11.0 (source-compatible since 2.0)
278      */
279     public ToStringHelper add(String name, int value) {
280       return addHolder(name, String.valueOf(value));
281     }
282 
283     /**
284      * Adds a name/value pair to the formatted output in {@code name=value}
285      * format.
286      *
287      * @since 11.0 (source-compatible since 2.0)
288      */
289     public ToStringHelper add(String name, long value) {
290       return addHolder(name, String.valueOf(value));
291     }
292 
293     /**
294      * Adds an unnamed value to the formatted output.
295      *
296      * <p>It is strongly encouraged to use {@link #add(String, Object)} instead
297      * and give value a readable name.
298      */
299     public ToStringHelper addValue(@Nullable Object value) {
300       return addHolder(value);
301     }
302 
303     /**
304      * Adds an unnamed value to the formatted output.
305      *
306      * <p>It is strongly encouraged to use {@link #add(String, boolean)} instead
307      * and give value a readable name.
308      *
309      * @since 11.0 (source-compatible since 2.0)
310      */
311     public ToStringHelper addValue(boolean value) {
312       return addHolder(String.valueOf(value));
313     }
314 
315     /**
316      * Adds an unnamed value to the formatted output.
317      *
318      * <p>It is strongly encouraged to use {@link #add(String, char)} instead
319      * and give value a readable name.
320      *
321      * @since 11.0 (source-compatible since 2.0)
322      */
323     public ToStringHelper addValue(char value) {
324       return addHolder(String.valueOf(value));
325     }
326 
327     /**
328      * Adds an unnamed value to the formatted output.
329      *
330      * <p>It is strongly encouraged to use {@link #add(String, double)} instead
331      * and give value a readable name.
332      *
333      * @since 11.0 (source-compatible since 2.0)
334      */
335     public ToStringHelper addValue(double value) {
336       return addHolder(String.valueOf(value));
337     }
338 
339     /**
340      * Adds an unnamed value to the formatted output.
341      *
342      * <p>It is strongly encouraged to use {@link #add(String, float)} instead
343      * and give value a readable name.
344      *
345      * @since 11.0 (source-compatible since 2.0)
346      */
347     public ToStringHelper addValue(float value) {
348       return addHolder(String.valueOf(value));
349     }
350 
351     /**
352      * Adds an unnamed value to the formatted output.
353      *
354      * <p>It is strongly encouraged to use {@link #add(String, int)} instead
355      * and give value a readable name.
356      *
357      * @since 11.0 (source-compatible since 2.0)
358      */
359     public ToStringHelper addValue(int value) {
360       return addHolder(String.valueOf(value));
361     }
362 
363     /**
364      * Adds an unnamed value to the formatted output.
365      *
366      * <p>It is strongly encouraged to use {@link #add(String, long)} instead
367      * and give value a readable name.
368      *
369      * @since 11.0 (source-compatible since 2.0)
370      */
371     public ToStringHelper addValue(long value) {
372       return addHolder(String.valueOf(value));
373     }
374 
375     /**
376      * Returns a string in the format specified by {@link
377      * Objects#toStringHelper(Object)}.
378      *
379      * <p>After calling this method, you can keep adding more properties to later
380      * call toString() again and get a more complete representation of the
381      * same object; but properties cannot be removed, so this only allows
382      * limited reuse of the helper instance. The helper allows duplication of
383      * properties (multiple name/value pairs with the same name can be added).
384      */
385     @Override public String toString() {
386       // create a copy to keep it consistent in case value changes
387       boolean omitNullValuesSnapshot = omitNullValues;
388       String nextSeparator = "";
389       StringBuilder builder = new StringBuilder(32).append(className)
390           .append('{');
391       for (ValueHolder valueHolder = holderHead.next; valueHolder != null;
392           valueHolder = valueHolder.next) {
393         if (!omitNullValuesSnapshot || valueHolder.value != null) {
394           builder.append(nextSeparator);
395           nextSeparator = ", ";
396 
397           if (valueHolder.name != null) {
398             builder.append(valueHolder.name).append('=');
399           }
400           builder.append(valueHolder.value);
401         }
402       }
403       return builder.append('}').toString();
404     }
405 
406     private ValueHolder addHolder() {
407       ValueHolder valueHolder = new ValueHolder();
408       holderTail = holderTail.next = valueHolder;
409       return valueHolder;
410     }
411 
412     private ToStringHelper addHolder(@Nullable Object value) {
413       ValueHolder valueHolder = addHolder();
414       valueHolder.value = value;
415       return this;
416     }
417 
418     private ToStringHelper addHolder(String name, @Nullable Object value) {
419       ValueHolder valueHolder = addHolder();
420       valueHolder.value = value;
421       valueHolder.name = checkNotNull(name);
422       return this;
423     }
424 
425     private static final class ValueHolder {
426       String name;
427       Object value;
428       ValueHolder next;
429     }
430   }
431 }